home *** CD-ROM | disk | FTP | other *** search
/ Apple WWDC 1996 / WWDC96_1996 (CD).toast / Technology Materials / MacApp Release 10 / MacApp Release 10 - HD Ready / Libraries / Framework / Sources / UDocument.cp < prev    next >
Encoding:
Text File  |  1996-04-03  |  51.4 KB  |  1,699 lines  |  [TEXT/MPS ]

  1. //----------------------------------------------------------------------------------------
  2. // UDocument.cp 
  3. // Copyright © 1984-96 by Apple Computer, Inc. All rights reserved.
  4. //----------------------------------------------------------------------------------------
  5.  
  6. #ifndef __UDOCUMENT__
  7. #include "UDocument.h"
  8. #endif
  9.  
  10. // MacApp
  11.  
  12. //    #ifndef __UAPPLICATION__
  13. //    #include "UApplication.h"
  14. //    #endif
  15.  
  16. #ifndef __UBEHAVIOR__
  17. #include "UBehavior.h"
  18. #endif
  19.  
  20. #ifndef __UCLIPBOARDMGR__
  21. #include "UClipboardMgr.h"
  22. #endif
  23.  
  24. #ifndef __UCOREERRORMGR__
  25. #include "UCoreErrorMgr.h"
  26. #endif
  27.  
  28. #ifndef __UCOREGLOBALS__
  29. #include "UCoreGlobals.h"
  30. #endif
  31.  
  32. #ifndef __UCOREUTILITIES__
  33. #include "UCoreUtilities.h"
  34. #endif
  35.  
  36. #ifndef __UDESIGNATOR__
  37. #include "UDesignator.h"
  38. #endif
  39.  
  40. #ifndef __UDISPATCHER__
  41. #include "UDispatcher.h"
  42. #endif
  43.  
  44. #ifndef __UERRORMGR__
  45. #include "UErrorMgr.h"
  46. #endif
  47.  
  48. #ifndef __UMACAPPGLOBALS__
  49. #include "UMacAppGlobals.h"
  50. #endif
  51.  
  52. #ifndef __UMACAPPUTILITIES__
  53. #include "UMacAppUtilities.h"
  54. #endif
  55.  
  56. #ifndef __UMEMORY__
  57. #include "UMemory.h"
  58. #endif
  59.  
  60. #ifndef __UMENUMGR__
  61. #include "UMenuMgr.h"
  62. #endif
  63.  
  64. #ifndef __UPRINTHANDLER__
  65. #include "UPrintHandler.h"
  66. #endif
  67.  
  68. #ifndef __USCRIPTABLEOBJECT__
  69. #include "UScriptableObject.h"
  70. #endif
  71.  
  72. #ifndef __USCRIPTING__
  73. #include "UScripting.h"
  74. #endif
  75.  
  76. #ifndef __UVIEWSERVER__
  77. #include "UViewServer.h"
  78. #endif
  79.  
  80. #ifndef __UWINDOW__
  81. #include "UWindow.h"
  82. #endif
  83.  
  84. // Toolbox
  85.  
  86. #ifndef __AEREGISTRY__
  87. #include <AERegistry.h>
  88. #endif
  89.  
  90. //========================================================================================
  91. // static data members
  92. //========================================================================================
  93. short TDocument::gNumUntitled = 1;                            // call the first document "Untitled-1"
  94.  
  95.  
  96. //========================================================================================
  97. // CLASS CWindowIterator
  98. //========================================================================================
  99. #undef Inherited
  100. #define Inherited CObjectIterator
  101.  
  102. //----------------------------------------------------------------------------------------
  103. // CWindowIterator::CWindowIterator: 
  104. //----------------------------------------------------------------------------------------
  105. #pragma segment MAViewRes
  106.  
  107. CWindowIterator::CWindowIterator(const TDocument* itsDocument,
  108.                            ArrayIndex itsLowBound,
  109.                            ArrayIndex itsHighBound,
  110.                            Boolean itsForward) :
  111.     CObjectIterator(itsDocument ? itsDocument->fWindowList : NULL, itsLowBound, itsHighBound, itsForward)
  112. {
  113. } // CWindowIterator::CWindowIterator 
  114.  
  115. //----------------------------------------------------------------------------------------
  116. // CWindowIterator::CWindowIterator: 
  117. //----------------------------------------------------------------------------------------
  118. #pragma segment MADocumentRes
  119.  
  120. CWindowIterator::CWindowIterator(const TDocument* itsDocument,
  121.                            Boolean itsForward) :
  122.     CObjectIterator(itsDocument ? itsDocument->fWindowList : NULL, itsForward)
  123. {
  124. } // CWindowIterator::CWindowIterator 
  125.  
  126. //----------------------------------------------------------------------------------------
  127. // CWindowIterator::CWindowIterator: 
  128. //----------------------------------------------------------------------------------------
  129. #pragma segment MADocumentRes
  130.  
  131. CWindowIterator::CWindowIterator(const TDocument* itsDocument) :
  132.     CObjectIterator(itsDocument ? itsDocument->fWindowList : NULL, kIterateForward)
  133. {
  134. } // CWindowIterator::CWindowIterator 
  135.  
  136. //----------------------------------------------------------------------------------------
  137. // CWindowIterator::~CWindowIterator: 
  138. //----------------------------------------------------------------------------------------
  139. #pragma segment IteratorRes
  140.  
  141. CWindowIterator::~CWindowIterator()
  142. {
  143. } // CWindowIterator::~CWindowIterator 
  144.  
  145. //========================================================================================
  146. // CLASS TRevertDocCommand
  147. //========================================================================================
  148. #undef Inherited
  149. #define Inherited TCommand
  150.  
  151. #pragma segment MASelCommand
  152. MA_DEFINE_CLASS_M1(TRevertDocCommand, Inherited);
  153.  
  154. //----------------------------------------------------------------------------------------
  155. // TRevertDocCommand constructor
  156. //----------------------------------------------------------------------------------------
  157. #pragma segment MASelCommand
  158.  
  159. TRevertDocCommand::TRevertDocCommand()
  160.     : fChangedDocument(NULL),
  161.       fInProcessP(NULL)
  162. {
  163. } // TRevertDocCommand::TRevertDocCommand
  164.  
  165. //----------------------------------------------------------------------------------------
  166. // TRevertDocCommand destructor
  167. //----------------------------------------------------------------------------------------
  168. #pragma segment MADestructorRes
  169.  
  170. TRevertDocCommand::~TRevertDocCommand()
  171. {
  172.     if (fInProcessP != NULL)
  173.         *fInProcessP = FALSE;
  174. }
  175.  
  176. //----------------------------------------------------------------------------------------
  177. // TRevertDocCommand::DoIt: 
  178. //----------------------------------------------------------------------------------------
  179. #pragma segment MAReadFile
  180.  
  181. void TRevertDocCommand::DoIt()
  182. {
  183.     fChangedDocument->RevertDocument();
  184.     fChangedDocument->ShowReverted();
  185.     if (fInProcessP != NULL)
  186.         *fInProcessP = FALSE;
  187. } // TRevertDocCommand::DoIt 
  188.  
  189. //----------------------------------------------------------------------------------------
  190. // TRevertDocCommand::IRevertDocCommand: 
  191. //----------------------------------------------------------------------------------------
  192. #pragma segment MASelCommand
  193.  
  194. Boolean TRevertDocCommand::IRevertDocCommand(CommandNumber itsCommandNumber,
  195.                                              TDocument* itsDocument)
  196. {
  197.     this->ICommand(itsCommandNumber, itsDocument, kCantUndo, kDoesNotCauseChange, itsDocument);
  198.     fChangedDocument = itsDocument;
  199.  
  200.     // Ask them if they are sure they want to revert.
  201.     FailOSErr(MAInteractWithUser());
  202.     CStr255 name;
  203.     fChangedDocument->GetTitle(name);
  204.  
  205.     ParamText(name, gEmptyString, gEmptyString, gEmptyString);
  206.     return (MacAppAlert(phRevert, NULL) == kYesButton);
  207. } // TRevertDocCommand::IRevertDocCommand 
  208.  
  209.  
  210. //----------------------------------------------------------------------------------------
  211. // TRevertDocCommand::IRevertDocCommand
  212. //----------------------------------------------------------------------------------------
  213. #pragma segment MASelCommand
  214.  
  215. void TRevertDocCommand::IRevertDocCommand(TDocument* itsDocument,
  216.                                           TAppleEvent* /* message */,
  217.                                           TAppleEvent* /* reply */,
  218.                                           Boolean* statusP)
  219. {
  220.     this->ICommand(cRevert, itsDocument, kCantUndo, kDoesNotCauseChange, itsDocument);
  221.     fChangedDocument = itsDocument;
  222.     fInProcessP = statusP;
  223.     if (fInProcessP != NULL)
  224.         *fInProcessP = TRUE;
  225. }
  226.  
  227. //----------------------------------------------------------------------------------------
  228. // TRevertDocCommand::MakeAppleEvent: 
  229. //----------------------------------------------------------------------------------------
  230. #pragma segment MACommandRes
  231.  
  232. TAppleEvent* TRevertDocCommand::MakeAppleEvent()
  233. {
  234.     MAVolatileInit(TAppleEvent*, mayFailEvent, NULL);
  235.  
  236.     FailInfo fi;
  237.     Try(fi)
  238.     {
  239.         TAppleEvent*    theEvent = new TAppleEvent;
  240.         theEvent->IAppleEvent(kAEMiscStandards, kAERevert, gServerAddress, kAEWaitReply);
  241.         mayFailEvent = theEvent;
  242.  
  243.         // Add the document as the direct object
  244.         {
  245.             CTempDesc docDesc;
  246.             fChangedDocument->MakeObjectSpecifier(docDesc, formName);
  247.             theEvent->WriteParameter(keyDirectObject, docDesc);
  248.         }
  249.  
  250.         fi.Success();
  251.     }
  252.     else                                // Recover
  253.     {
  254.         mayFailEvent = (TAppleEvent *)FreeIfObject(mayFailEvent);
  255.         fi.ReSignal();
  256.     }
  257.     return mayFailEvent;
  258. }
  259.  
  260. //========================================================================================
  261. // CLASS TSaveDocCommand
  262. //========================================================================================
  263. #undef Inherited
  264. #define Inherited TCommand
  265.  
  266. #pragma segment MASelCommand
  267. MA_DEFINE_CLASS_M1(TSaveDocCommand, Inherited);
  268.  
  269. //----------------------------------------------------------------------------------------
  270. // TSaveDocCommand constructor
  271. //----------------------------------------------------------------------------------------
  272. #pragma segment MASelCommand
  273.  
  274. TSaveDocCommand::TSaveDocCommand()
  275.     : fDocument(NULL),
  276.       fSavingState(kAskSave),
  277.       fMessage(NULL),
  278.       fReply(NULL)
  279. {
  280. }
  281.  
  282. //----------------------------------------------------------------------------------------
  283. // TSaveDocCommand destructor
  284. //----------------------------------------------------------------------------------------
  285. #pragma segment MADestructorRes
  286.  
  287. TSaveDocCommand::~TSaveDocCommand()
  288. {
  289.     // NOTE: We deliberately do not dispose of fMessage and fReply.
  290. }
  291.  
  292. //----------------------------------------------------------------------------------------
  293. // TSaveDocCommand::ISaveDocCommand: 
  294. //----------------------------------------------------------------------------------------
  295. #pragma segment MASelCommand
  296.  
  297. void TSaveDocCommand::ISaveDocCommand(CommandNumber itsCommandNumber,
  298.                                       TDocument* itsDocument)
  299. {
  300.     this->ICommand(itsCommandNumber, itsDocument,  kCantUndo,
  301.                    kDoesNotCauseChange, NULL);
  302.     fDocument = itsDocument;
  303.     fSavingState = kDoSave;
  304. }
  305.  
  306. //----------------------------------------------------------------------------------------
  307. // TSaveDocCommand::ISaveDocCommand: 
  308. //----------------------------------------------------------------------------------------
  309. #pragma segment MASelCommand
  310.  
  311. void TSaveDocCommand::ISaveDocCommand(TDocument* itsDocument,
  312.                                       TAppleEvent* message,
  313.                                       TAppleEvent* reply)
  314. {
  315.     // This doesn't actually prepare to save anything since we don't have any idea
  316.     // what kind of document you have.
  317.     CommandNumber    itsCommandNumber = cSave;
  318.     
  319.     this->ICommand(itsCommandNumber, itsDocument, kCantUndo,
  320.                    kDoesNotCauseChange, NULL);
  321.     
  322.     fMessage = message;
  323.     fReply = reply;
  324.     fDocument = itsDocument;
  325.     fSavingState = kDoSave;        // Default so no data is inadvertantly lost.
  326. }
  327.  
  328. //----------------------------------------------------------------------------------------
  329. // TSaveDocCommand::DoIt: 
  330. //----------------------------------------------------------------------------------------
  331. #pragma segment MAClose
  332.  
  333. void TSaveDocCommand::DoIt()
  334. {
  335.     if (fDocument && fSavingState != kDontSave && fDocument->fCommitOnSave)
  336.         fDocument->CommitLastCommand();
  337. }
  338.  
  339. //----------------------------------------------------------------------------------------
  340. // TSaveDocCommand::MakeAppleEvent: 
  341. //----------------------------------------------------------------------------------------
  342. #pragma segment MACommandRes
  343.  
  344. TAppleEvent* TSaveDocCommand::MakeAppleEvent()
  345. {
  346.     MAVolatileInit(TAppleEvent*, mayFailEvent, NULL);
  347.     FailInfo fi;
  348.     Try(fi)
  349.     {
  350.         TAppleEvent*    theEvent = new TAppleEvent;
  351.         theEvent->IAppleEvent(kAECoreSuite, kAESave, gServerAddress, kAEWaitReply);
  352.         mayFailEvent = theEvent;
  353.         {
  354.             CTempDesc theDocDesc;
  355.             fDocument->MakeObjectSpecifier(theDocDesc, fDocument->GetSpecifierForm());
  356.             theEvent->WriteParameter(keyDirectObject, theDocDesc);
  357.         }
  358.         fi.Success();
  359.     }
  360.     else                                // Recover
  361.     {
  362.         mayFailEvent = (TAppleEvent *)FreeIfObject(mayFailEvent);
  363.         fi.ReSignal();
  364.     }
  365.     return mayFailEvent;
  366. }
  367.  
  368. //========================================================================================
  369. // CLASS TCloseDocCommand
  370. //========================================================================================
  371. #undef Inherited
  372. #define Inherited TCommand
  373.  
  374. #pragma segment MASelCommand
  375. MA_DEFINE_CLASS_M1(TCloseDocCommand, Inherited);
  376.  
  377. //----------------------------------------------------------------------------------------
  378. // TCloseDocCommand constructor
  379. //----------------------------------------------------------------------------------------
  380. #pragma segment MASelCommand
  381.  
  382. TCloseDocCommand::TCloseDocCommand()
  383.     : fDocument(NULL),
  384.       fSavingState(kUnknown),
  385.       fMessage(NULL),
  386.       fReply(NULL)
  387. {
  388. }
  389.  
  390. //----------------------------------------------------------------------------------------
  391. // TCloseDocCommand destructor
  392. //----------------------------------------------------------------------------------------
  393. #pragma segment MADestructorRes
  394.  
  395. TCloseDocCommand::~TCloseDocCommand()
  396. {
  397.     // NOTE: We deliberately do not dispose of fMessage and fReply.
  398. }
  399.  
  400. //----------------------------------------------------------------------------------------
  401. // TCloseDocCommand::ICloseDocCommand: 
  402. //----------------------------------------------------------------------------------------
  403. #pragma segment MASelCommand
  404.  
  405. void TCloseDocCommand::ICloseDocCommand(CommandNumber itsCommandNumber,
  406.                                         TDocument* itsDocument)
  407. {
  408.     this->ICommand(itsCommandNumber, itsDocument,  kCantUndo,
  409.                    kDoesNotCauseChange, NULL);
  410.  
  411.     fDocument = itsDocument;
  412.  
  413.     //    // If this command is to notify another command then do a link.
  414.     //    if (linkedCommand)
  415.     //        this->LinkToSecondary(linkedCommand);
  416.  
  417.     if (fDocument->IsChanged())    // 3.5
  418.     {
  419.         if (fDocument->fAskOnClose)
  420.         {
  421. //            FailInfo fi;
  422. //            Try(fi)
  423. //            {
  424.             short poseResult = fDocument->PoseSaveDialog();
  425.             switch (poseResult)
  426.             {
  427.                 case kNoButton:
  428.                     fSavingState = kDontSave;
  429.                     break;
  430.                 case kYesButton:
  431.                     fSavingState = kDoSave;
  432.                     break;
  433.                 case cancel:
  434.                     FailOSErr(userCanceledErr);
  435.                     break;
  436.             }
  437. //                fi.Success();
  438. //            }
  439. //            else
  440. //            {
  441. //                this->SetValidationError(fi.error);    // In case we are linked.
  442. //                fi.ReSignal();
  443. //            }
  444.         }
  445.         else
  446.             fSavingState = kDoSave;
  447.     }
  448.     else
  449.         fSavingState = kDontSave;
  450. }
  451.  
  452. //----------------------------------------------------------------------------------------
  453. // TCloseDocCommand::ICloseDocCommand: 
  454. //----------------------------------------------------------------------------------------
  455. #pragma segment MASelCommand
  456.  
  457. void TCloseDocCommand::ICloseDocCommand(TDocument* itsDocument,
  458.                                         TAppleEvent* message,
  459.                                         TAppleEvent* reply)
  460. {
  461.     this->ICommand(cClose, itsDocument,  kCantUndo,
  462.                         kDoesNotCauseChange, NULL);
  463.     
  464.     fDocument = itsDocument;
  465.     fMessage = message;
  466.     fReply = reply;
  467.     fSavingState = kDoSave;
  468.  
  469.     //    // If this command is to notify another command then do a link.
  470.     //    if (linkedCommand)
  471.     //        this->LinkToSecondary(linkedCommand);
  472.  
  473. //    FailInfo fi;
  474. //    Try(fi)
  475. //    {
  476.     // Does the AppleEvent specifically say not to save?
  477.     Boolean hasSaveOptions = message->HasParameter(keyAESaveOptions);
  478.     if (hasSaveOptions)
  479.     {
  480.         // Get the save options
  481.         DescType theSaveOption = message->ReadEnum(keyAESaveOptions);
  482.         if (theSaveOption == kAEAsk)
  483.             fSavingState = kAskSave;
  484.         else if (theSaveOption == kAENo)
  485.             fSavingState = kDontSave;
  486.     }
  487.     else if (fDocument->fAskOnClose)
  488.     {
  489.         short poseResult = fDocument->PoseSaveDialog();
  490.         switch (poseResult)
  491.         {
  492.             case kNoButton:
  493.                 fSavingState = kDontSave;
  494.                 break;
  495.             case kYesButton:
  496.                 fSavingState = kDoSave;
  497.                 break;
  498.             case cancel:
  499.                 FailOSErr(userCanceledErr);
  500.                 break;
  501.         }
  502.     }
  503. //        fi.Success();
  504. //    }
  505. //    else // Recover
  506. //    {
  507. //        this->SetValidationError(fi.error);    // In case we are linked.
  508. //        fi.ReSignal();
  509. //    }
  510. }
  511.  
  512. //----------------------------------------------------------------------------------------
  513. // TCloseDocCommand::DoIt: 
  514. //----------------------------------------------------------------------------------------
  515. #pragma segment MAClose
  516.  
  517. void TCloseDocCommand::DoIt()
  518. {
  519.     if (fDocument)
  520.     {
  521.         if (fSavingState != kDontSave && fDocument->fCommitOnSave)
  522.             fDocument->CommitLastCommand();
  523.             
  524.         // If there is actually some saving to do it should have already been done.
  525.         fDocument->SetChangeCount(0);    // Force it to not save since it will have
  526.                                         // already have been saved if desired by user.
  527.         fDocument->CloseAndFree();
  528.     }
  529. }
  530.  
  531. //----------------------------------------------------------------------------------------
  532. // TCloseDocCommand::MakeAppleEvent: 
  533. //----------------------------------------------------------------------------------------
  534. #pragma segment MACommandRes
  535.  
  536. TAppleEvent* TCloseDocCommand::MakeAppleEvent()
  537. {
  538.     MAVolatileInit(TAppleEvent*, mayFailEvent, NULL);
  539.     if (fSavingState != kCancelled)
  540.     {
  541.         FailInfo fi;
  542.         Try(fi)
  543.         {
  544.             TAppleEvent*    theEvent = new TAppleEvent;
  545.             theEvent->IAppleEvent(kAECoreSuite, kAEClose, gServerAddress, kAEWaitReply);
  546.             mayFailEvent = theEvent;
  547.             {
  548.                 CTempDesc theDocDesc;
  549.                 fDocument->MakeObjectSpecifier(theDocDesc, fDocument->GetSpecifierForm());
  550.                 theEvent->WriteParameter(keyDirectObject, theDocDesc);
  551.             }
  552.             // What kind of saving is desired.
  553.             DescType theSaveOption = kAEAsk;
  554.             if (fSavingState == kDoSave)
  555.                 theSaveOption = kAEYes;
  556.             else if (fSavingState == kDontSave)
  557.                 theSaveOption = kAENo;
  558.             theEvent->WriteEnum(keyAESaveOptions, theSaveOption);
  559.     
  560.             fi.Success();
  561.         }
  562.         else // Recover
  563.         {
  564.             mayFailEvent = (TAppleEvent *)FreeIfObject(mayFailEvent);
  565.             fi.ReSignal();
  566.         }
  567.     }
  568.     return mayFailEvent;
  569. }
  570.  
  571. //========================================================================================
  572. // CLASS TDocument
  573. //========================================================================================
  574. #undef Inherited
  575. #define Inherited TCommandHandler
  576.  
  577. #pragma segment MAOpen
  578.  
  579. MA_DEFINE_CLASS_M2(TDocument, Inherited, MScriptableObject);
  580.  
  581. //----------------------------------------------------------------------------------------
  582. // TDocument constructor
  583. //----------------------------------------------------------------------------------------
  584. #pragma segment MAOpen
  585.  
  586. TDocument::TDocument()
  587.     : MScriptableObject(cDocument),
  588.       fWindowList(NULL),
  589.       fViewList(NULL),
  590.       fPrintInfo(NULL),
  591.       fChangeCount(0),
  592.       fUserSelection(NULL),
  593.       fSavePrintInfo(TRUE),
  594.       fSaveUserSelection(TRUE),
  595. #if qAttachable
  596.       fSaveAttachedScript(TRUE),
  597. #endif
  598.       fSharePrintInfo(TRUE),
  599.       fReopenAlert(FALSE),
  600.       fCommitOnSave(TRUE),
  601.       fAskOnClose(TRUE),
  602.       fIsGhostDocument(FALSE)
  603. {
  604. }
  605.  
  606. //----------------------------------------------------------------------------------------
  607. // TDocument::IDocument: 
  608. //----------------------------------------------------------------------------------------
  609. #pragma segment MAOpen
  610.  
  611. void TDocument::IDocument()
  612. {
  613.     this->ICommandHandler(gDispatcher);
  614.  
  615.     FailInfo fi;
  616.     Try(fi)
  617.     {
  618.         gDispatcher->AddDocument(this);
  619.  
  620.         fWindowList = NewList();
  621. #if qDebug
  622.         fWindowList->SetEltType(&TWindow::fgClassDesc);
  623. #endif
  624.  
  625.         fViewList = NewList();
  626. #if qDebug
  627.         fViewList->SetEltType(&TView::fgClassDesc);
  628. #endif
  629.  
  630.         fi.Success();
  631.     }
  632.     else    // Recover
  633.     {
  634.         this->Free();
  635.         fi.ReSignal();
  636.     }
  637. } // TDocument::IDocument 
  638.  
  639. //----------------------------------------------------------------------------------------
  640. // TDocument::Free: 
  641. //----------------------------------------------------------------------------------------
  642. #pragma segment MAClose
  643.  
  644. TDocument::~TDocument()
  645. {
  646.     gDispatcher->DeleteDocument(this);
  647.  
  648.     fWindowList = (TList *)FreeListIfObject(fWindowList);
  649.     fViewList = (TList *)FreeListIfObject(fViewList);
  650.  
  651.     // Always drop my reference
  652.     fPrintInfo = fSharePrintInfo ? (TPrintInfo*)FreeIfObject((TObject*)(void*)fPrintInfo) : NULL; // coerce b/c this is a stub definition
  653.  
  654.     fUserSelection = (TDesignator *)FreeIfObject(fUserSelection);
  655. }
  656.  
  657. //----------------------------------------------------------------------------------------
  658. // TDocument::AddView: 
  659. //----------------------------------------------------------------------------------------
  660. #pragma segment MAOpen
  661.  
  662. void TDocument::AddView(TView* aView)
  663. {
  664.     // Protect against double installation and keep in synch with window list 
  665.  
  666.     if (fViewList && (fViewList->GetIdentityItemNo(aView) == 0))
  667.         fViewList->Insert(aView);
  668. } // TDocument::AddView 
  669.  
  670. //----------------------------------------------------------------------------------------
  671. // TDocument::AddWindow: 
  672. //----------------------------------------------------------------------------------------
  673. #pragma segment MAOpen
  674.  
  675. void TDocument::AddWindow(TWindow* aWindow)
  676. {
  677.     // Protect against double installation and keep in synch with window list 
  678.     // doesn't already exist in list
  679.     
  680.     if (fWindowList && (fWindowList->GetIdentityItemNo(aWindow) == 0))
  681.         fWindowList->Insert(aWindow);
  682. } // TDocument::AddWindow 
  683.  
  684. //----------------------------------------------------------------------------------------
  685. // TDocument::FindDocument: 
  686. //----------------------------------------------------------------------------------------
  687. #pragma segment MARes
  688.  
  689. Boolean TDocument::FindDocument(TFile*)
  690. {
  691.     return FALSE;
  692. } // TDocument::FindDocument 
  693.  
  694. //----------------------------------------------------------------------------------------
  695. // TDocument::AttachPrintHandler: 
  696. //----------------------------------------------------------------------------------------
  697. #pragma segment MAOpen
  698.  
  699. void TDocument::AttachPrintHandler(TPrintHandler* itsPrintHandler)
  700. {
  701.     if (itsPrintHandler)
  702.         itsPrintHandler->fDocument = this;
  703.  
  704.     TPrintMenuBehavior* aPrintMenuBehavior = new TPrintMenuBehavior;
  705.     aPrintMenuBehavior->IPrintMenuBehavior(itsPrintHandler);
  706.     this->AddBehavior(aPrintMenuBehavior);
  707.     if (!fPrintInfo && fSharePrintInfo)
  708.         fPrintInfo = itsPrintHandler->GetPrintInfo();
  709. } // TDocument::AttachPrintHandler 
  710.  
  711. //----------------------------------------------------------------------------------------
  712. // TDocument::DetachPrintHandler: 
  713. //----------------------------------------------------------------------------------------
  714. #pragma segment MAOpen
  715.  
  716. void TDocument::DetachPrintHandler(TPrintHandler* itsPrintHandler)
  717. {
  718.     TBehavior* itsManager = itsPrintHandler->GetManager();
  719.     if (itsManager)
  720.     {
  721.         this->RemoveBehavior(itsManager);
  722.         FreeIfObject(itsManager);
  723.     }
  724. } // TDocument::DetachPrintHandler 
  725.  
  726. //----------------------------------------------------------------------------------------
  727. // TDocument::Changed: 
  728. //----------------------------------------------------------------------------------------
  729. #pragma segment MARes
  730. void TDocument::Changed(ChangeID theChange,
  731.                                TObject* changedBy)    // override 
  732. {
  733.     switch (theChange)
  734.     {
  735.         case cUndo:
  736.             --fChangeCount;
  737.             break;
  738.         default:
  739.             // protect from rollover (it goes negative). If your document has
  740.             // this many changes (over 2 billion) you are truly sick!
  741.             this->SetChangeCount(Max(this->GetChangeCount() + 1, 1));
  742.             break;
  743.     }
  744.     Inherited::Changed(theChange, changedBy);    // Notify dependents 
  745. } // TDocument::Changed 
  746.  
  747. //----------------------------------------------------------------------------------------
  748. // TDocument::OpenWindowCount: 
  749. //----------------------------------------------------------------------------------------
  750. #pragma segment MAClose
  751.  
  752. short TDocument::OpenWindowCount()
  753. {
  754.     short openDocWindows = 0;
  755.     CWindowIterator iter(this);
  756.  
  757.     // See how many open windows this document has 
  758.     for (TWindow* aWindow = iter.FirstWindow(); iter.More(); aWindow = iter.NextWindow())
  759.         if (aWindow->IsShown() && !aWindow->fFloats)
  760.             ++openDocWindows;
  761.     return openDocWindows;
  762. } // TDocument::OpenWindowCount 
  763.  
  764. //----------------------------------------------------------------------------------------
  765. // TDocument::CloseWindow: 
  766. //----------------------------------------------------------------------------------------
  767. #pragma segment MAClose
  768.  
  769. void TDocument::CloseWindow(TWindow* aWindow)
  770. {
  771.     // The default behavior is: if the window's fClosesDocument is TRUE
  772.     // OR if this is the document's last open window then close the
  773.     // document, otherwise just close the window.  In either case
  774.     // the action must be recordable.
  775.  
  776.     if (aWindow && (aWindow->fDocument == this))    // free window 
  777.     {
  778.         if (this->OpenWindowCount() <= 1 && !aWindow->fFloats && aWindow->IsShown())
  779.             this->DoClose(cClose);            // The window will be closed and freed 
  780.         else                                // as a side effect        
  781.             aWindow->DoClose(cClose);
  782.     }
  783. } // TDocument::CloseWindow 
  784.  
  785. //----------------------------------------------------------------------------------------
  786. // TDocument::Close: 
  787. //----------------------------------------------------------------------------------------
  788. #pragma segment MAClose
  789.  
  790. void TDocument::Close()
  791. {
  792.     this->Changed(mClosed,this);
  793.  
  794.     // Must never be called for a document related to a view in the Clipboard.
  795.     CWindowIterator iter(this);
  796.  
  797.     for (TWindow* aWindow = iter.FirstWindow(); iter.More(); aWindow = iter.NextWindow())
  798.         aWindow->CloseAndFree();
  799. } // TDocument::Close 
  800.  
  801. //----------------------------------------------------------------------------------------
  802. // TDocument::CloseAndFree: 
  803. //----------------------------------------------------------------------------------------
  804. #pragma segment MAClose
  805.  
  806. void TDocument::CloseAndFree()
  807. {
  808.     this->Close();
  809.     this->Free();
  810. } // TDocument::CloseAndFree 
  811.  
  812. //----------------------------------------------------------------------------------------
  813. // TDocument::MakeCloseCommand: 
  814. //----------------------------------------------------------------------------------------
  815. #pragma segment MAClose
  816.  
  817. TCloseDocCommand* TDocument::MakeCloseCommand()
  818. {
  819.     TCloseDocCommand* aCloseCommand = new TCloseDocCommand;
  820.     aCloseCommand->ICloseDocCommand(cClose, this);
  821.     return aCloseCommand;
  822. }
  823.  
  824. //----------------------------------------------------------------------------------------
  825. // TDocument::DoClose: 
  826. //----------------------------------------------------------------------------------------
  827. #pragma segment MAClose
  828.  
  829. void TDocument::DoClose(CommandNumber aCommand,
  830.                         Boolean useAppleEvent)
  831. {
  832.     Boolean oldTempAlloc = TemporaryAllocation(TRUE);
  833.     Boolean oldObjectPerm = AllocateObjectsFromPerm(FALSE);
  834.     TCloseDocCommand* aCloseDocCommand = new TCloseDocCommand;
  835.     aCloseDocCommand->ICloseDocCommand(aCommand, this);
  836.     aCloseDocCommand->fUseAppleEvent = useAppleEvent;
  837.     
  838.     this->PostCommand(aCloseDocCommand);
  839.  
  840.     TemporaryAllocation(oldTempAlloc);
  841.     AllocateObjectsFromPerm(oldObjectPerm);
  842. }
  843.  
  844. //----------------------------------------------------------------------------------------
  845. // TDocument::DeleteView: 
  846. //----------------------------------------------------------------------------------------
  847. #pragma segment MAClose
  848.  
  849. void TDocument::DeleteView(TView* viewToDelete)
  850. {
  851.     if (fViewList)
  852.         fViewList->Delete(viewToDelete);
  853.  
  854.     // Make sure the lists are in synch.
  855.     if (fWindowList)
  856.         fWindowList->Delete(viewToDelete);
  857. } // TDocument::DeleteView 
  858.  
  859. //----------------------------------------------------------------------------------------
  860. // TDocument::DeleteWindow: 
  861. //----------------------------------------------------------------------------------------
  862. #pragma segment MAClose
  863.  
  864. void TDocument::DeleteWindow(TWindow* windowToDelete)
  865. {
  866.     if (fWindowList)
  867.         fWindowList->Delete(windowToDelete);
  868.  
  869.     // Make sure the lists are in synch.
  870.     if (fViewList)
  871.         fViewList->Delete(windowToDelete);
  872. } // TDocument::DeleteWindow 
  873.  
  874. //----------------------------------------------------------------------------------------
  875. // TDocument::DoInitialState: Called for 'New' && 'Revert' [to blank] commands && for
  876. // default open tool icon
  877. //----------------------------------------------------------------------------------------
  878. #pragma segment MAOpen
  879.  
  880. void TDocument::DoInitialState()
  881. {
  882. } // TDocument::DoInitialState 
  883.  
  884. //----------------------------------------------------------------------------------------
  885. // TDocument::DoMakeViews: 
  886. //
  887. //     E X A M P L E
  888. //    {
  889. //        TYOURView*    aYOURView;
  890. //        aYOURView = new TYourView;
  891. //        aYOURView->IYOURView(this, YOURExtentRect);
  892. //        return aYOURView;
  893. //    }
  894. //----------------------------------------------------------------------------------------
  895. #pragma segment MAOpen
  896.  
  897. void TDocument::DoMakeViews(Boolean forPrinting)
  898. {
  899. #if qTemplateViews
  900.     TView * aView = NULL;
  901.  
  902.     if (forPrinting)                        // Don't need window when Finder printing. 
  903.         aView = gViewServer->DoCreateViews(this, NULL, kDefaultViewID, gZeroVPt);
  904.     else
  905.         aView = gViewServer->NewTemplateWindow(kDefaultWindowID, this);
  906.         
  907.     InstallIfPrintHandler(TPrintHandler::gPrintHandler, aView);
  908. #endif
  909. } // TDocument::DoMakeViews 
  910.  
  911. //----------------------------------------------------------------------------------------
  912. // TDocument::DoPostMakeViews: 
  913. //----------------------------------------------------------------------------------------
  914. #pragma segment MAOpen
  915.  
  916. void TDocument::DoPostMakeViews(Boolean forPrinting)
  917. {
  918.     if (!forPrinting)
  919.         this->ShowWindows();
  920.     
  921.     TDesignator* userSelection = this->GetUserSelection();
  922.     if (userSelection)
  923.         this->RevealSelection(userSelection);
  924. } // TDocument::DoPostMakeViews 
  925.  
  926. //----------------------------------------------------------------------------------------
  927. // TDocument::DoMenuCommand: 
  928. //----------------------------------------------------------------------------------------
  929. #pragma segment MASelCommand
  930.  
  931. void TDocument::DoMenuCommand(CommandNumber aCommandNumber)
  932. {
  933.     //====================================================================================
  934.     // Some commands will be posted to perform actions that must _ALWAYS_ be available.
  935.     // The allocation cannot be allowed to fail. So we do a temp allocation which by
  936.     // definition cannot be allowed to fail. This strategy is used wherever we want to use
  937.     // command objects but don't want to leave the user twisting in the breeze. NOTE:
  938.     // Don't forget to allow for this memory in your mem! resource if you copy this style
  939.     // in your own code.
  940.     //====================================================================================
  941.  
  942.     switch (aCommandNumber)
  943.     {
  944.         case cUndo:
  945.             if (!gDispatcher->DoUndoRedo(this, aCommandNumber, this))
  946.                 Inherited::DoMenuCommand(aCommandNumber);
  947.             break;
  948.  
  949.         case cSave:
  950.         case cSaveAs:
  951.         case cSaveCopy:
  952.             this->DoSave(aCommandNumber);
  953.             break;
  954.  
  955.         case cRevert:
  956.             {
  957.                 Boolean oldTempAlloc = TemporaryAllocation(TRUE);
  958.                 Boolean oldObjectPerm = AllocateObjectsFromPerm(FALSE);
  959.                 TRevertDocCommand* aRevertDocCommand = new TRevertDocCommand;
  960.                 Boolean proceed = aRevertDocCommand->IRevertDocCommand(aCommandNumber, this);
  961.                 
  962.                 if (proceed)
  963.                 {
  964.                     aRevertDocCommand->fUseAppleEvent = TRUE;    // This is the difference!
  965.                     this->PostCommand(aRevertDocCommand);
  966.                 }
  967.                 else
  968.                     aRevertDocCommand->Free();
  969.  
  970.                 TemporaryAllocation(oldTempAlloc);
  971.                 AllocateObjectsFromPerm(oldObjectPerm);
  972.             }
  973.             break;
  974.  
  975.         default:
  976.             Inherited::DoMenuCommand(aCommandNumber);
  977.             break;
  978.     }
  979. } // TDocument::DoMenuCommand 
  980.  
  981. //----------------------------------------------------------------------------------------
  982. // TDocument::DoSetupMenus: 
  983. //----------------------------------------------------------------------------------------
  984. #pragma segment MADocumentRes
  985.  
  986. void TDocument::DoSetupMenus()
  987. {
  988.     Inherited::DoSetupMenus();
  989.  
  990.     Enable(cSaveAs, TRUE);
  991.     Enable(cSaveCopy, TRUE);
  992.     if (this->IsChanged())    // 3.5
  993.     {
  994.         Enable(cSave, TRUE);
  995.         Enable(cRevert, TRUE);
  996.     }
  997. } // TDocument::DoSetupMenus 
  998.  
  999. //----------------------------------------------------------------------------------------
  1000. // TDocument::FreeData: 
  1001. //----------------------------------------------------------------------------------------
  1002. #pragma segment MADocumentRes
  1003.  
  1004. void TDocument::FreeData()
  1005. {
  1006. } // TDocument::FreeData 
  1007.  
  1008. //----------------------------------------------------------------------------------------
  1009. // TDocument::FreeFromClipboard: 
  1010. //----------------------------------------------------------------------------------------
  1011. #pragma segment MAClipboard
  1012.  
  1013. void TDocument::FreeFromClipboard()
  1014. {
  1015.     this->DeleteWindow(gClipboardMgr->fClipWindow);
  1016.  
  1017.     this->Free();
  1018. } // TDocument::FreeFromClipboard 
  1019.  
  1020. //----------------------------------------------------------------------------------------
  1021. // TDocument::GetIsGhostDocument: 
  1022. //----------------------------------------------------------------------------------------
  1023. #pragma segment MADocumentRes
  1024.  
  1025. Boolean TDocument::GetIsGhostDocument() const
  1026. {
  1027.     return fIsGhostDocument;
  1028. } // TDocument::GetIsGhostDocument
  1029.  
  1030. //----------------------------------------------------------------------------------------
  1031. // TDocument::SetIsGhostDocument: 
  1032. //----------------------------------------------------------------------------------------
  1033. #pragma segment MADocumentRes
  1034.  
  1035. void TDocument::SetIsGhostDocument(const Boolean newIsGhostDocument)
  1036. {
  1037.     fIsGhostDocument = newIsGhostDocument;
  1038. } // TDocument::SetIsGhostDocument
  1039.  
  1040. //----------------------------------------------------------------------------------------
  1041. // TDocument::RegainControl: 
  1042. //----------------------------------------------------------------------------------------
  1043. #pragma segment MADocumentRes
  1044.  
  1045. void TDocument::RegainControl()
  1046. {
  1047. }
  1048.  
  1049. //----------------------------------------------------------------------------------------
  1050. // TDocument::GetChangeCount: 
  1051. //----------------------------------------------------------------------------------------
  1052. #pragma segment MADocumentRes
  1053.  
  1054. long TDocument::GetChangeCount()
  1055. {
  1056.     return fChangeCount;
  1057. } // TDocument::GetChangeCount 
  1058.  
  1059. // Added for 3.5:
  1060. //----------------------------------------------------------------------------------------
  1061. // TDocument::IsChanged: 
  1062. //----------------------------------------------------------------------------------------
  1063. #pragma segment MADocumentRes
  1064.  
  1065. Boolean TDocument::IsChanged()
  1066. {
  1067.     return GetChangeCount() > 0;
  1068. } // TDocument::IsChanged 
  1069.  
  1070. //----------------------------------------------------------------------------------------
  1071. // TDocument::DoWriteData: 
  1072. //----------------------------------------------------------------------------------------
  1073. #pragma segment MADocumentRes
  1074.  
  1075. void TDocument::DoWriteData(const OSType /* aScrapType */,
  1076.                                    TDesignator* /* aDesignator */,
  1077.                                    TStream* /* aStream */)
  1078. {
  1079.     this->SubClassResponsibility();
  1080. } // TDocument::DoWriteData 
  1081.  
  1082. //----------------------------------------------------------------------------------------
  1083. // TDocument::DoReadData: 
  1084. //----------------------------------------------------------------------------------------
  1085. #pragma segment MADocumentRes
  1086.  
  1087. void TDocument::DoReadData(const OSType /* aScrapType */,
  1088.                                   TDesignator* /* aDesignator */,
  1089.                                   TStream* /* aStream */,
  1090.                                   long /* count */)
  1091. {
  1092.     this->SubClassResponsibility();
  1093. } // TDocument::DoReadData 
  1094.  
  1095. //----------------------------------------------------------------------------------------
  1096. // TDocument::GetUserSelection: 
  1097. //----------------------------------------------------------------------------------------
  1098. #pragma segment MAViewRes
  1099.  
  1100. TDesignator* TDocument::GetUserSelection()
  1101. {
  1102.     return fUserSelection;
  1103. } // TDocument::GetUserSelection 
  1104.  
  1105. //----------------------------------------------------------------------------------------
  1106. // TDocument::SetUserSelection: 
  1107. //----------------------------------------------------------------------------------------
  1108. #pragma segment MAViewRes
  1109.  
  1110. void TDocument::SetUserSelection(TDesignator* newSelection)
  1111. {
  1112.     if (newSelection != fUserSelection)
  1113.     {
  1114.         fUserSelection = (TDesignator *)FreeIfObject(fUserSelection);
  1115.         fUserSelection = newSelection;
  1116.     }
  1117. } // TDocument::SetUserSelection 
  1118.  
  1119. //----------------------------------------------------------------------------------------
  1120. // TDocument::UserSelectionChanged: 
  1121. //----------------------------------------------------------------------------------------
  1122. #pragma segment MAViewRes
  1123.  
  1124. void TDocument::UserSelectionChanged(TView* /* changedView */)
  1125. {
  1126. } // TDocument::UserSelectionChanged 
  1127.  
  1128. //----------------------------------------------------------------------------------------
  1129. // TDocument::RevealSelection: 
  1130. //----------------------------------------------------------------------------------------
  1131. #pragma segment MADocumentNonRes
  1132.  
  1133. void TDocument::RevealSelection(TDesignator* /* designator */)
  1134. {
  1135.     // Default behavior: select the first window of the application.
  1136.     // Call Inherited::RevealSelection() to get this default behavior if you need it.
  1137.     
  1138.     if (fWindowList)
  1139.     {
  1140.         TWindow* window = NULL;
  1141.         if ((window = (TWindow *)fWindowList->First()) != NULL)
  1142.         {
  1143.             if (!window->IsActive())
  1144.                 window->Select();
  1145.         }
  1146.     }
  1147. } // TDocument::RevealSelection 
  1148.  
  1149. //----------------------------------------------------------------------------------------
  1150. // TDocument::RevealUndoRedo:
  1151. //----------------------------------------------------------------------------------------
  1152. #pragma segment MAApplicationRes
  1153.  
  1154. void TDocument::RevealUndoRedo(TCommand* command) // override
  1155. {
  1156.     Inherited::RevealUndoRedo(command);
  1157.     
  1158.     if (fWindowList)
  1159.     {
  1160.         TWindow* window = (TWindow *)fWindowList->First();
  1161.         if (window)
  1162.             window->Select();
  1163.     }
  1164. }
  1165.  
  1166. //----------------------------------------------------------------------------------------
  1167. // TDocument::OpenAgain: 
  1168. //----------------------------------------------------------------------------------------
  1169. #pragma segment MAOpen
  1170.  
  1171. void TDocument::OpenAgain(CommandNumber /*commandNumber*/,
  1172.                           TDocument* /*document*/)
  1173. {
  1174.     if (fReopenAlert)
  1175.     {
  1176.         OSErr interactErr = MAInteractWithUser();
  1177.         if (interactErr == noErr)
  1178.         {
  1179.             ParamText(fTitle, gEmptyString, gEmptyString, gEmptyString);
  1180.             StdAlert(phReopenDoc);
  1181.         }
  1182.         else if (interactErr != errAENoUserInteraction)
  1183.             FailOSErr(interactErr);
  1184.     }
  1185.     
  1186.     if (fWindowList)
  1187.     {
  1188.         TWindow* window = (TWindow *)fWindowList->First();
  1189.         if (window)
  1190.             window->Select(); 
  1191.     }
  1192. } // TDocument::OpenAgain 
  1193.  
  1194. //----------------------------------------------------------------------------------------
  1195. // TDocument::PoseSaveDialog: 
  1196. //----------------------------------------------------------------------------------------
  1197. #pragma segment MAClose
  1198.  
  1199. short TDocument::PoseSaveDialog()
  1200. {
  1201.     short returnVal = kNoButton;
  1202.  
  1203.     if (this->IsChanged())    // 3.5
  1204.     {
  1205.         FailOSErr(MAInteractWithUser());
  1206.  
  1207.         CStr255 reason;
  1208.         GetIndString(reason, kIDBuzzString, gDispatcher->fDone ? bzQuitting : bzClosing);
  1209.  
  1210.         CStr255 apName;
  1211.         gDispatcher->GetApplicationName(apName);    // Get the application name 
  1212.         ParamText(fTitle, reason, apName, gEmptyString);
  1213.         returnVal = MacAppAlert(phSaveChanges, NULL);
  1214.     }
  1215.  
  1216.     return returnVal;
  1217. } // TDocument::PoseSaveDialog 
  1218.  
  1219. //----------------------------------------------------------------------------------------
  1220. // TDocument::ReadDocument: 
  1221. //----------------------------------------------------------------------------------------
  1222. #pragma segment MAReadFile
  1223.  
  1224. void TDocument::ReadDocument(Boolean)
  1225. {
  1226.     this->SubClassResponsibility();
  1227. } // TDocument::ReadDocument 
  1228.  
  1229. //----------------------------------------------------------------------------------------
  1230. // TDocument::ReadStationery: 
  1231. //----------------------------------------------------------------------------------------
  1232. #pragma segment MAReadFile
  1233.  
  1234. void TDocument::ReadStationery(TFile*)
  1235. {
  1236.     this->SubClassResponsibility();
  1237. } // TDocument::ReadStationery 
  1238.  
  1239. //----------------------------------------------------------------------------------------
  1240. // TDocument::RevertDocument: 
  1241. //----------------------------------------------------------------------------------------
  1242. #pragma segment MAReadFile
  1243.  
  1244. void TDocument::RevertDocument()
  1245. {
  1246.     this->SubClassResponsibility();
  1247. } // TDocument::RevertDocument 
  1248.  
  1249.  
  1250. //----------------------------------------------------------------------------------------
  1251. // TDocument::Abandon: 
  1252. //----------------------------------------------------------------------------------------
  1253. #pragma segment MAClose
  1254.  
  1255. void TDocument::Abandon()
  1256. {
  1257.     // If your document needs to do some cleanup when its being abandoned then
  1258.     // put some code in an override of this method
  1259. } // TDocument::Abandon 
  1260.  
  1261. //----------------------------------------------------------------------------------------
  1262. // TDocument::GetSaveLocation
  1263. //----------------------------------------------------------------------------------------
  1264. #pragma segment MASelCommand
  1265.  
  1266. void TDocument::GetSaveLocation(CommandNumber /*itsCommandNumber*/, CAEDesc& /*theSaveDesc*/)
  1267. // Creates an CAEDesc describing where the document would be saved
  1268. {
  1269. }
  1270.  
  1271. //----------------------------------------------------------------------------------------
  1272. // TDocument::DoSave
  1273. //----------------------------------------------------------------------------------------
  1274. #pragma segment MASelCommand
  1275.  
  1276. void TDocument::DoSave(CommandNumber itsCommandNumber)
  1277. {
  1278.     // Generate a save document command.
  1279.     Boolean oldTempAlloc = TemporaryAllocation(TRUE);
  1280.     Boolean oldObjectPerm = AllocateObjectsFromPerm(FALSE);
  1281.     TSaveDocCommand* aSaveDocCommand = new TSaveDocCommand;
  1282.  
  1283.     aSaveDocCommand->ISaveDocCommand(itsCommandNumber, this);
  1284.     aSaveDocCommand->fUseAppleEvent = TRUE;    // This is the difference!
  1285.     this->PostCommand(aSaveDocCommand);
  1286.  
  1287.     TemporaryAllocation(oldTempAlloc);
  1288.     AllocateObjectsFromPerm(oldObjectPerm);
  1289. }
  1290.  
  1291. //----------------------------------------------------------------------------------------
  1292. // TDocument::SaveDocument: 
  1293. //----------------------------------------------------------------------------------------
  1294. #pragma segment MAWriteFile
  1295.  
  1296. void TDocument::SaveDocument(CommandNumber)
  1297. {
  1298.     this->SubClassResponsibility();
  1299. } // TDocument::SaveDocument 
  1300.  
  1301. //----------------------------------------------------------------------------------------
  1302. // TDocument::SaveAgain: 
  1303. //----------------------------------------------------------------------------------------
  1304. #pragma segment MAWriteFile
  1305.  
  1306. void TDocument::SaveAgain(CommandNumber,
  1307.                                  TDocument* savingDoc)
  1308. {
  1309.     // Don't save the file if another one of the same name is already open. 
  1310.     if (savingDoc != this)
  1311.         Failure(errSaveAgain, 0);
  1312. } // TDocument::SaveAgain 
  1313.  
  1314. //----------------------------------------------------------------------------------------
  1315. // TDocument::GetTitle: 
  1316. //----------------------------------------------------------------------------------------
  1317. #pragma segment MADocumentRes
  1318.  
  1319. void TDocument::GetTitle(CStr255& aTitle)
  1320. {
  1321.     aTitle = fTitle;
  1322. } // TDocument::GetTitle 
  1323.  
  1324. //----------------------------------------------------------------------------------------
  1325. // TDocument::SetTitle: 
  1326. //----------------------------------------------------------------------------------------
  1327. #pragma segment MADocumentRes
  1328.  
  1329. void TDocument::SetTitle(const CStr255& aTitle)
  1330. {
  1331.     CWindowIterator iter(this);
  1332.     
  1333.     fTitle = aTitle;
  1334.     for (TWindow* aWindow = iter.FirstWindow(); iter.More(); aWindow = iter.NextWindow())
  1335.         aWindow->SetTitleForDoc(aTitle);
  1336. } // TDocument::SetTitle 
  1337.  
  1338. //----------------------------------------------------------------------------------------
  1339. // TDocument::SetChangeCount: 
  1340. //----------------------------------------------------------------------------------------
  1341. #pragma segment MADocumentRes
  1342.  
  1343. void TDocument::SetChangeCount(long newChangeCount)
  1344. {
  1345.     fChangeCount = newChangeCount;
  1346. } // TDocument::SetChangeCount 
  1347.  
  1348. //----------------------------------------------------------------------------------------
  1349. // TDocument::ShowReverted: 
  1350. //----------------------------------------------------------------------------------------
  1351. #pragma segment MAReadFile
  1352.  
  1353. void TDocument::ShowReverted()
  1354. {
  1355.     CWindowIterator iter(this);
  1356.     
  1357.     for (TWindow* aWindow = iter.FirstWindow(); iter.More(); aWindow = iter.NextWindow())
  1358.         aWindow->ShowReverted();
  1359. } // TDocument::ShowReverted 
  1360.  
  1361. //----------------------------------------------------------------------------------------
  1362. // TDocument::ShowWindows: 
  1363. //----------------------------------------------------------------------------------------
  1364. #pragma segment MAOpen
  1365.  
  1366. void TDocument::ShowWindows()
  1367. {
  1368.     CWindowIterator iter(this, kIterateBackward);
  1369.     
  1370.     // Make the windows open from back to front 
  1371.     for (TWindow* aWindow = iter.FirstWindow(); iter.More(); aWindow = iter.NextWindow())
  1372.         if (aWindow->fOpenInitially)
  1373.             aWindow->Open();
  1374. } // TDocument::ShowWindows 
  1375.  
  1376. //----------------------------------------------------------------------------------------
  1377. // TDocument::UntitledName: 
  1378. //----------------------------------------------------------------------------------------
  1379. #pragma segment MAOpen
  1380.  
  1381. void TDocument::UntitledName(CStr255& noName)
  1382. {
  1383.     short preInsert;
  1384.     short constChars;
  1385.     CStr255 num;
  1386.     
  1387.     if (gNumUntitled == 1) {
  1388.         GetIndString(noName, kIDBuzzString, bzFirstUntitled);
  1389.             gNumUntitled++;
  1390.     }
  1391.     else {
  1392.         GetIndString(noName, kIDBuzzString, bzUntitled);
  1393.         NumToString(gNumUntitled, num);
  1394.         if (ParseTitleTemplate(noName, preInsert, constChars) && 
  1395.           SubstituteInTitle(noName, num, preInsert, constChars))
  1396.             gNumUntitled++;
  1397.     }
  1398. } // TDocument::UntitledName 
  1399.  
  1400. //----------------------------------------------------------------------------------------
  1401. // Scripting Support
  1402. //----------------------------------------------------------------------------------------
  1403.  
  1404. //----------------------------------------------------------------------------------------
  1405. // TDocument::GetSpecifierForm: 
  1406. //----------------------------------------------------------------------------------------
  1407. #pragma segment MAScriptingRes
  1408.  
  1409. DescType TDocument::GetSpecifierForm()
  1410. {
  1411.     return formName;
  1412. } // TDocument::GetSpecifierForm
  1413.  
  1414. //----------------------------------------------------------------------------------------
  1415. // TDocument::GetObjectProperty: 
  1416. //----------------------------------------------------------------------------------------
  1417. #pragma segment MAScriptingRes
  1418.  
  1419. Boolean TDocument::GetObjectProperty(CAEDesc& thePropertyValue,
  1420.                                      DescType whichProperty,
  1421.                                      const CAEDesc& desiredType)
  1422. {
  1423.     Boolean hasProperty = TRUE;
  1424.     
  1425.     FailInfo fi;
  1426.     Try(fi)
  1427.     {
  1428.         switch (whichProperty)
  1429.         {
  1430.             case pIsModified:
  1431.                 {
  1432.                     Boolean modified = IsChanged();    // 3.5
  1433.                     thePropertyValue.PutBoolean(modified);
  1434.                 }
  1435.                 break;
  1436.     
  1437.             case pName:
  1438.                 {
  1439.                     CStr255 theDocName;
  1440.                     GetTitle(theDocName);
  1441.                     thePropertyValue.PutString(theDocName);
  1442.                 }
  1443.                 break;
  1444.                 
  1445.             case pIndex:
  1446.                 {
  1447.                     // locate the nth window and return its associated document
  1448.                     hasProperty = FALSE;
  1449.                     MScriptableObject *myContainer = GetObjectsContainer();
  1450.                     long numWindows = myContainer->CountContainedObjects(cWindow);
  1451.                     for (long index = 1; index <= numWindows; index++)
  1452.                     {
  1453.                         TWindow *indexedWindow = 
  1454.                                 (TWindow *)myContainer->GetIndContainedObject(cWindow, index);
  1455.                         CTempDesc objectDesc;
  1456.                         objectDesc.PutObject(indexedWindow->fDocument);
  1457.                         if (this->CompareScriptableObjects(kAEEquals, objectDesc))
  1458.                         {
  1459.                             thePropertyValue.PutLong(index);
  1460.                             hasProperty = TRUE;
  1461.                             break;
  1462.                         }
  1463.                     }
  1464.                 }
  1465.                 break;
  1466.     
  1467.             default:
  1468.                 hasProperty = MScriptableObject::GetObjectProperty(thePropertyValue, whichProperty, desiredType);
  1469.                 break;
  1470.         }
  1471.         fi.Success();
  1472.     }
  1473.     else // Recover
  1474.     {
  1475.         hasProperty = FALSE;
  1476.     }
  1477.     return hasProperty;
  1478. }
  1479.  
  1480. //----------------------------------------------------------------------------------------
  1481. // TDocument::GetSetPropertyInfo: 
  1482. //----------------------------------------------------------------------------------------
  1483. #pragma segment MAScriptingRes
  1484.  
  1485. void TDocument::GetSetPropertyInfo(DescType whichProperty,
  1486.                                 CommandNumber& cmdNum,
  1487.                                 Boolean& canUndo,
  1488.                                 Boolean& causesChange,
  1489.                                 TCommandHandler* &theContext)
  1490. {
  1491.     MScriptableObject::GetSetPropertyInfo(whichProperty, cmdNum, canUndo,
  1492.         causesChange, theContext);
  1493.     
  1494.     if (whichProperty == pName)
  1495.     {
  1496.         canUndo = FALSE;
  1497.         causesChange = FALSE;
  1498.     }
  1499. }
  1500.  
  1501. //----------------------------------------------------------------------------------------
  1502. // TDocument::SetObjectProperty: 
  1503. //----------------------------------------------------------------------------------------
  1504. #pragma segment MAScriptingRes
  1505.  
  1506. void TDocument::SetObjectProperty(const CAEDesc& thePropertyValue,
  1507.                                              DescType whichProperty)
  1508. {
  1509.     switch (whichProperty)
  1510.     {
  1511.         case pName:
  1512.             {
  1513.                 CStr255 theDocName;
  1514.                 thePropertyValue.GetString(theDocName);
  1515.                 SetTitle(theDocName);
  1516.             }
  1517.             break;
  1518.  
  1519.         case pIsModified:
  1520.             FailOSErr(errAECantSetReadOnly);
  1521.             break;
  1522.  
  1523.         default:
  1524.             MScriptableObject::SetObjectProperty(thePropertyValue, whichProperty);
  1525.             break;
  1526.     }
  1527. }
  1528.  
  1529. //----------------------------------------------------------------------------------------
  1530. // TDocument::GetContainedObject: 
  1531. //----------------------------------------------------------------------------------------
  1532. #pragma segment OSLDispatchRes
  1533.  
  1534. MScriptableObject* TDocument::GetContainedObject(DescType desiredType,
  1535.                                               DescType selectionForm,
  1536.                                               const CAEDesc& selectionData)
  1537. {
  1538.     MScriptableObject * result = NULL;
  1539.     CAEDesc theSelectionData = selectionData;
  1540.     if ((desiredType == cProperty) && (theSelectionData.GetType() == pSelection))
  1541.         result = this->GetUserSelection();
  1542.     else
  1543.         result = MScriptableObject::GetContainedObject(desiredType, selectionForm, selectionData);
  1544.     return result;
  1545. }
  1546.  
  1547. //----------------------------------------------------------------------------------------
  1548. // TDocument::DoAESetData: 
  1549. //----------------------------------------------------------------------------------------
  1550. #pragma segment MAScriptingRes
  1551.  
  1552. void TDocument::DoAESetData(TAppleEvent*/* message */  ,
  1553.                                     TAppleEvent* /* reply */)
  1554. {
  1555.     // Handles the SetData AppleEvent from the Core Suite.
  1556.     // TDocument overrides this method so it can handle this event
  1557.     // and avoid an event not handled error, but
  1558.     // it doesn't actually do anything with the data. 
  1559. }
  1560.  
  1561. //----------------------------------------------------------------------------------------
  1562. // TDocument::DoAEClose: 
  1563. //----------------------------------------------------------------------------------------
  1564. #pragma segment MAScriptingRes
  1565.  
  1566. void TDocument::DoAEClose(TAppleEvent* message,
  1567.                           TAppleEvent* reply)
  1568. {
  1569.     Boolean oldTempAlloc = TemporaryAllocation(TRUE);
  1570.     Boolean oldObjectPerm = AllocateObjectsFromPerm(FALSE);
  1571.     TCloseDocCommand* aCloseDocCommand = NULL;
  1572.     Boolean inProcess = TRUE;
  1573.  
  1574.     aCloseDocCommand = new TCloseDocCommand;
  1575.     aCloseDocCommand->ICloseDocCommand(this, message, reply);
  1576.  
  1577.     // Process the command immediately rather than posting it.
  1578.     aCloseDocCommand->Process();
  1579.  
  1580.     TemporaryAllocation(oldTempAlloc);
  1581.     AllocateObjectsFromPerm(oldObjectPerm);
  1582. }
  1583.  
  1584. //----------------------------------------------------------------------------------------
  1585. // TDocument::DoAERevert
  1586. //----------------------------------------------------------------------------------------
  1587. #pragma segment MAOSLDispatch
  1588.  
  1589. void TDocument::DoAERevert(TAppleEvent*    message,
  1590.                            TAppleEvent* reply)
  1591. {
  1592.     MAVolatileInit(Boolean, oldTempAlloc, TemporaryAllocation(TRUE));
  1593.     MAVolatileInit(Boolean, oldObjectPerm, AllocateObjectsFromPerm(FALSE));
  1594.     MAVolatileInit(TRevertDocCommand*, aRevertDocCommand, NULL);
  1595.     Boolean inProcess = TRUE;
  1596.  
  1597.     FailInfo fi;
  1598.     Try(fi)
  1599.     {
  1600.         aRevertDocCommand = new TRevertDocCommand;
  1601.         aRevertDocCommand->IRevertDocCommand(this, message, reply, &inProcess);
  1602.  
  1603.         this->PostCommand(aRevertDocCommand);
  1604.  
  1605.         // Now we're going modal until we're sure the command
  1606.         // has completed successfully.
  1607.         while (inProcess)
  1608.             gDispatcher->PollEvent(kAllowApplicationToSleep);
  1609.  
  1610.         TemporaryAllocation(oldTempAlloc);
  1611.         AllocateObjectsFromPerm(oldObjectPerm);
  1612.  
  1613.         fi.Success();
  1614.     }
  1615.     else                                // Recover
  1616.     {
  1617.         FreeIfObject(aRevertDocCommand);
  1618.         TemporaryAllocation(oldTempAlloc);
  1619.         AllocateObjectsFromPerm(oldObjectPerm);
  1620.  
  1621.         fi.ReSignal();
  1622.     }
  1623. }
  1624.  
  1625. //----------------------------------------------------------------------------------------
  1626. // TDocument::DoAESave
  1627. //----------------------------------------------------------------------------------------
  1628. #pragma segment MAScriptingRes
  1629.  
  1630. void TDocument::DoAESave(TAppleEvent* message,
  1631.                          TAppleEvent* reply)
  1632. {
  1633.     // Generate a save document command.
  1634.     Boolean oldTempAlloc = TemporaryAllocation(TRUE);
  1635.     Boolean oldObjectPerm = AllocateObjectsFromPerm(FALSE);
  1636.     TSaveDocCommand* aSaveDocCommand = NULL;
  1637.  
  1638.     aSaveDocCommand = new TSaveDocCommand();
  1639.     aSaveDocCommand->ISaveDocCommand(this, message, reply);
  1640.  
  1641.     // Process the command immediately rather than posting it.
  1642.     aSaveDocCommand->Process();
  1643.  
  1644.     TemporaryAllocation(oldTempAlloc);
  1645.     AllocateObjectsFromPerm(oldObjectPerm);
  1646. }
  1647.  
  1648.  
  1649. //----------------------------------------------------------------------------------------
  1650. // TDocument::DoScriptCommand
  1651. //----------------------------------------------------------------------------------------
  1652. #pragma segment AMailerRes
  1653.  
  1654. void TDocument::DoScriptCommand(CommandNumber     aCommandNumber,
  1655.                                 TAppleEvent*     message,
  1656.                                 TAppleEvent*     reply)
  1657. {
  1658.     switch (aCommandNumber)
  1659.     {
  1660.         case cAEUndo:
  1661.         case cAERedo:
  1662.             if (CommandEnabled(cUndo))
  1663.                 gDispatcher->UndoRedoInContext(this, aCommandNumber);
  1664.             break;
  1665.             
  1666.         case cAERevert:
  1667.             DoAERevert(message, reply);
  1668.             break;
  1669.  
  1670.         default:
  1671.             MScriptableObject::DoScriptCommand(aCommandNumber, message, reply);
  1672.             break;
  1673.     }
  1674. }
  1675.  
  1676. //----------------------------------------------------------------------------------------
  1677. // Container Application Support
  1678. //----------------------------------------------------------------------------------------
  1679.  
  1680. #if qContainer
  1681.  
  1682. //----------------------------------------------------------------------------------------
  1683. // TDocument::GetContainer: 
  1684. //----------------------------------------------------------------------------------------
  1685. #pragma segment MADocumentRes
  1686.  
  1687. CADocumentRef TDocument::GetContainer()
  1688. {
  1689.     // Override to return the container document reference
  1690.     return NULL;
  1691. } // TDocument::GetContainer 
  1692.  
  1693. #endif // qContainer
  1694.  
  1695. //----------------------------------------------------------------------------------------
  1696. // End of UDocument.cp
  1697.  
  1698. #pragma segment Inline
  1699.